home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / tex / tabx10.zip / TABX.C < prev    next >
Text File  |  1990-03-03  |  7KB  |  228 lines

  1. /* TABX.C - tab expansion utility */
  2. /* Written by  Baruch Nissenbaum  - Tel-Aviv University, Israel 2/1990  (c)  */
  3. /* E-mail: BARUCH@TAUNIVM.BITNET (BARUCH@TAUNIVM.TAU.AC.IL) or BARUCH@TAUENG */
  4. /* Comments, Suggestions and Ideas are welcomed. */
  5. /* Pleas do not modify the above note or the 'FREE DISTRIBUTION ONLY' note */
  6.  
  7. /* This program should work for a file of any size, and any line length.  */
  8. /* Compiled and tested with TURBO-C, should work with any other compiler. */
  9. /* See usage() for details of operation. */
  10.  
  11. /* Options are linked in a kind of link list manner, where the list is
  12.    made up from functions calling each other via function pointers.
  13.    This unique arrangement makes the program very modular, Anyone can
  14.    add new filters very easily following the example below. Note, however,
  15.    that the price is execution time. Each option adds one function call for
  16.    each character in the output file. */
  17.  
  18.  
  19. #include <stdio.h>
  20. #include <ctype.h>
  21. #include <string.h>
  22.  
  23. typedef (filter)(int);  /* a filter function */
  24. typedef filter *fptr;   /* a pointer to a filter function */
  25.  
  26. /* each filter function has its corresponding output variable */
  27. int     fputchar(int);
  28. int     no_trail(int);         /* a function */
  29. fptr    put_tr = &fputchar;    /* its output pointer */
  30. int     conv_up(int);          /* etc. ... */
  31. fptr    put_up = &fputchar;
  32. int     conv_low(int);
  33. fptr    put_low = &fputchar;
  34. int     capit(int);
  35. fptr    put_cap = &fputchar;
  36. int     strip(int);
  37. fptr    put_nud = &fputchar;
  38. int     number(int);
  39. fptr    put_num;
  40.  
  41. fptr put = &fputchar; /* output function called from main function */
  42.  
  43. /* output filter chaining */
  44. typedef struct {
  45.    fptr funct;     /* the filter function itself */
  46.    char flag;      /* flag that activates this function */
  47.    fptr *chain;    /* chain to the next filer */
  48. } filter_data;
  49.  
  50. filter_data  filters[]={  /* table of function and activating flags */
  51.   { no_trail, 'e', &put_tr },
  52.   { conv_up,  'u', &put_up },
  53.   { conv_low, 'l', &put_low },
  54.   { capit,    'c', &put_cap },
  55.   { strip,    's', &put_cap },
  56.   { number,   'n', &put_num },
  57.   { fputchar, '\0', NULL }}; /* terminator */
  58.  
  59. int insert_filter(filter_data *f)
  60. /* insert a filter before the current filter list */
  61. {
  62.    if(f->chain==NULL || f->flag=='\0')
  63.       return(1); /* error */
  64.    *(f->chain)=put; /* set the output */
  65.    put= f->funct;   /* link the input to function f */
  66.    return(0); /* ok */
  67. }
  68.  
  69. usage()
  70. {
  71.    fprintf(stderr,"      TABX  - tab expansion utility\n");
  72.    fprintf(stderr,"      This program expands tab characters to spaces.\n");
  73.    fprintf(stderr,"usage:   TABX  [-flags] [tab_spec]  < source_file  > dest_file\n");
  74.    fprintf(stderr,"      tab_spec can be an integer for setting fixed tab spacing (default is 8),\n");
  75.    fprintf(stderr,"      tab_spec can also be a string as in:\n");
  76.    fprintf(stderr,"        TABX ---T---T-T---T  < in_file > out_file\n");
  77.    fprintf(stderr,"      In this case tab stops will match the position of the 'T' characters,\n");
  78.    fprintf(stderr,"      in the above example - tabs will be set to 4 8 10 and 14\n");
  79.    fprintf(stderr,"      There are no limits on file size or line length\n\n");
  80.    fprintf(stderr,"    Flags:\n");
  81.    fprintf(stderr,"       -e  Blank character are remover from END of lines.\n");
  82.    fprintf(stderr,"       -n  insert line numbers to the beginning of lines.\n");
  83.    fprintf(stderr,"       -u  Convert all character to upper case.\n");
  84.    fprintf(stderr,"       -l  Convert all character to lower.\n");
  85.    fprintf(stderr,"       -c  Capitalize words in the file.\n");
  86.    fprintf(stderr,"       -s  strip bit 8 from all characters.\n");
  87.    fprintf(stderr,"    Any combination of options and tab specs may be specified at any order\n\n");
  88.    fprintf(stderr,"  Written by Baruch Nissenbaum,  Israel,  27 Feb 90 (c)\n");
  89.    fprintf(stderr,"  E-Mail: BARUCH@TAUNIVM.BITNET (TAUNIVM.TAU.AC.IL)\n\n");
  90.    fprintf(stderr,"  Not for sale,  FREE distribution only!!\n\n");
  91. }
  92.  
  93. fputchar( int c )
  94. /* put char function */
  95. {
  96.    putchar( c );
  97. }
  98.  
  99. no_trail( int c )
  100. /* print a character but filter out trailing spaces */
  101. {
  102.    static state=0;
  103.    static int n;
  104.  
  105.    switch( state ) {
  106.    case 0:
  107.       if( isspace(c) )
  108.          state = n=1;
  109.       else
  110.          putchar( c );
  111.       break;
  112.    case 1:
  113.       if(c=='\n') {
  114.          putchar(c);
  115.          state=0;
  116.       }
  117.       else if( isspace(c) )
  118.          n++;
  119.       else {
  120.          for(;n;n--)
  121.             putchar(' ');
  122.          putchar( c );
  123.          state=0;
  124.       }
  125.       break;
  126.    }
  127. }
  128.  
  129. main(argc,argv)
  130. int argc;
  131. char **argv;
  132. {
  133.    int c,col=0,tab=8,dlen=0,k,i,j;
  134.    char *d;
  135.  
  136.    for(k=1;k<argc;k++) { /* parse arguments */
  137.       if(strchr(argv[k],'T') != NULL || strchr(argv[k],'t') )
  138.          dlen=strlen(d=argv[k]);
  139.       else if(argv[k][0]=='-') {  /* chain filters according to flags */
  140.          for(j=strlen(argv[k])-1; j>0; j--)
  141.             for(i=0,c=tolower(argv[k][j]); filters[i].flag!='\0'; i++)
  142.                if( filters[i].flag==c)
  143.                   insert_filter( &filters[i] );
  144.       }
  145.       else
  146.          tab=atoi(argv[k]);
  147.       if(tab<1) {
  148.          usage();
  149.          exit(0);
  150.       }
  151.    }
  152.    if(tab<1) {
  153.       usage();
  154.       exit(0);
  155.    }
  156.  
  157.    while((c=getchar()) != EOF)
  158.       if(c=='\t') {              /* expand tabs */
  159.          put(' ');  col++;   /* tab will generate at least one space */
  160.          for(; col<dlen && d[col]!='t' && d[col]!='T'; col++)
  161.             put(' ');        /* expansion of tabs (tab string) */
  162.          if( col>=dlen )
  163.             for(; col%tab; col++)
  164.                put(' ');     /* expansion of tabs (fixed spacing) */
  165.       }
  166.       else if(c=='\n' || c=='\r') {
  167.          put(c);
  168.          col=0;
  169.      }
  170.      else {                      /* any other character */
  171.         put(c);
  172.         col++;
  173.      }
  174. }
  175.  
  176. int conv_up( int c )
  177. /* convert a character to upper case */
  178. {
  179.    return( put_up( toupper(c)));
  180. }
  181.  
  182. int conv_low( int c )
  183. /* convert characters to lower case */
  184. {
  185.    return( put_low( tolower(c)));
  186. }
  187.  
  188. int capit( int c )
  189. /* capitalize sentences */
  190. {
  191.    static state=0;  /* start of a sentence */
  192.  
  193.    if(c=='.' || c==':' || c==';')  /* sentence terminators */
  194.       state=0;
  195.    else if(state==0 && !isspace(c)) {
  196.       if(islower(c))
  197.          c=toupper(c); /* capitalize */
  198.       state=1;   /* inside a sentence */
  199.    }
  200.    return( put_cap(c) );
  201. }
  202.  
  203. int strip( int c )
  204. /* strip bit 8 */
  205. {
  206.    return( put_nud(c & 0x7f) );
  207. }
  208.  
  209. int number( int c )
  210. /* add line numbers to beginning of lines */
  211. {
  212.    static long line_no=1;
  213.    static new_line=1;
  214.    char buff[20];
  215.    int i;
  216.  
  217.  
  218.    if(new_line && c!=EOF) {
  219.       sprintf(buff,"%4ld ",line_no++);
  220.       for(i=0; buff[i]!='\0'; i++)
  221.          put_num(buff[i]);
  222.       new_line=0;
  223.    }
  224.    if(c=='\n')
  225.       new_line=1;
  226.    return( put_num(c) );
  227. }
  228.